package models

import com.mongodb.casbah.Imports._
import com.mongodb.casbah.commons.conversions.scala._
import scala.collection.mutable.ArrayBuffer
import scala.collection.mutable.ListBuffer
import org.joda.time.DateTime
import org.joda.time.LocalDate
import org.joda.time.DateTimeConstants
import org.joda.time.format.DateTimeFormat
import org.joda.time.format.DateTimeFormatter

case class Task(uniqueID: Int,
  name: String,
  outlineNum: String,
  resourceName: String,
  startDate: String,
  finishDate: String,
  duration: String,
  percntComplete: Double) {

  def this(task: com.mongodb.casbah.Imports.DBObject) {
    this(task.as[Int]("UniqueID"),
      task.as[String]("Name"),
      task.as[String]("OutlineNum"),
      task.as[String]("ResourceName"),
      task.as[DateTime]("StartDate").toString(DateTimeFormat.forPattern("yyyy-MM-dd")),
      task.as[DateTime]("FinishDate").toString(DateTimeFormat.forPattern("yyyy-MM-dd")),
      task.as[String]("Duration"),
      task.as[Double]("PercntComplete"))
  }

}

object Task {

  val devs = ArrayBuffer("Tony Zhang",
    "Lei Zhang",
    "Yolanda Liu",
    "Ben An",
    "Terry Wang",
    "Wayne Wang",
    "Adward Tu",
    "Frank Li",
    "Gordon Cheng",
    "Morphy Tong",
    "Gary Chen",
    "Lucien Wang")

  RegisterJodaTimeConversionHelpers()
  val mongoCollection = MongoClient()("prjplan")("plan")
  val order = MongoDBObject("OutlineNum" -> 1)

  def all(): List[Task] = {
    for (rawtask <- mongoCollection.find().sort(order).toList) yield new Task(rawtask)
  }

  def byResource(resource: String): List[Task] = {

    val tasks = ArrayBuffer[Task]()
    val resourceObj = MongoDBObject("ResourceName" -> resource)
    for (rawtask <- mongoCollection.find(resourceObj).toList) yield new Task(rawtask)
  }

  def parentTasks(outlineNum: String): List[Task] = {
    val parentOutline = dropRightOfOutline(outlineNum)
    if (parentOutline.contains(".")) {
      val ourlineNum = MongoDBObject("OutlineNum" -> parentOutline)
      parentTasks(parentOutline) ++ (for (rawtask <- mongoCollection.findOne(ourlineNum).toList) yield (new Task(rawtask)))
    } else {
      List[Task]()
    }
  }

  def byResourceWithParent(resource: String): List[Task] = {

    val tasks = new ListBuffer[Task]()
    tasks ++= byResource(resource)

    tasks.foreach(task => tasks ++= parentTasks(task.outlineNum))

    tasks.distinct.toList.sortWith((t1, t2) => t1.outlineNum < t2.outlineNum)

  }

  //  def byPeriod() = {
  //    val today = new LocalDate()
  //    val weekStart = today.withDayOfWeek(DateTimeConstants.MONDAY)
  //    val weekEnd = today.withDayOfWeek(DateTimeConstants.SUNDAY)
  //    
  //    byPeriod(weekStart,weekEnd)
  //  }

  def byPeriod(startDate: DateTime, endDate: DateTime) = {
    val or = MongoDBObject("$or" -> MongoDBList("StartDate" $gte startDate $lte endDate, "FinishDate" $gte startDate $lte endDate))
    val q: MongoDBObject = or ++
      ("ResourceName" $in (devs))

    for (rawtask <- mongoCollection.find(q).toList) yield new Task(rawtask)
  }

  def inPeriod(date: DateTime) = {
    val q: MongoDBObject = ("StartDate" $lte date) ++
      ("FinishDate" $gt date) ++
      ("ResourceName" $in (devs))

    for (
      rawtask <- mongoCollection.find(q).toList
    ) yield new Task(rawtask)
  }

  def dropRightOfOutline(outline: String): String = {
    outline.substring(0, outline.lastIndexOf("."))
  }

  def release: List[Task] = {
    val tasks = ArrayBuffer[Task]()
    val releaseMonogoObject = MongoDBObject("OutlineNum" -> "^1..$".r)
    for (rawtask <- mongoCollection.find(releaseMonogoObject).toList) yield {
      val task=new Task(rawtask)
      
      task
      }
  }
  

}